This notebook is based on covid_19.Rmd. I created the present notebook because there was already too much information in covid_19.Rmd.

Methodology

1. Import files and packages

library(tidyr)
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(stringr)
library(readr)
library(lubridate)

Attaching package: ‘lubridate’

The following object is masked from ‘package:base’:

    date
deaths <- read_csv('covid_19_deaths.csv')
Parsed with column specification:
cols(
  Date = col_date(format = ""),
  `UK Deaths` = col_double(),
  `Global Deaths` = col_double()
)

2. inspect and clean the data


deaths <- deaths %>% mutate(infection_date=Date-days(14))
deaths <- deaths %>% rename(death_date=Date, deaths=`UK Deaths`)
uk_data <- deaths %>% select(-`Global Deaths`)
head(uk_data)

3. Add estimates of infections (three columns, showing a low, middle and a high estimate)

#add columns for various estimated death rates (0.1%, 0.5%, 1%, 2%, 3%)

uk_data <- uk_data %>% mutate(estimated_uk_cases_tenth=(deaths*1000))
uk_data <- uk_data %>% mutate(estimated_uk_cases_one=(deaths*100))
uk_data <- uk_data %>% mutate(estimated_uk_cases_two=(deaths*50))
uk_data
NA

4. clean the data again (reorder the columns)

# order should be two, one, tenth (as this shows the min-max range better)

5. create a new table that starts at 22nd March (since uk_data infection_date went up to 21st March at the time I created this code)

# using only estimates of 1% death rate and growth rate of doubling every 3-4 days (which means quadrupling in a week)

predictor <- function(previous_value) {
    predicted_value <- previous_value * 1.25
    return(predicted_value)
    }

# create predictions for each date
twentyTwoMarch <- 1.25 * 360500
twentyThreeMarch <- predictor(twentyTwoMarch)
twentyFourMarch <- predictor(twentyThreeMarch)
twentyFiveMarch <- predictor(twentyFourMarch)
twentySixMarch <- predictor(twentyFiveMarch)
twentySevenMarch <- predictor(twentySixMarch)
twentyEightMarch <- predictor(twentySevenMarch)
twentyNineMarch <- predictor(twentyEightMarch)
thirtyMarch <- predictor(twentyNineMarch)
thirtyOneMarch <- predictor(thirtyMarch)
oneApril <- predictor(thirtyOneMarch)
twoApril <- predictor(oneApril)
threeApril <- predictor(twoApril)
fourApril <- predictor(threeApril)
fiveApril <- predictor(fourApril)
sixApril <- predictor(fiveApril)
sevenApril <- predictor(sixApril)
eightApril <- predictor(sevenApril)
nineApril <- predictor(eightApril)
tenApril <- predictor(nineApril)
elevenApril <- predictor(tenApril)
twelveApril <- predictor(elevenApril)

thirteenApril <- predictor(twelveApril)
fourteenApril <- predictor(thirteenApril)
fifteenApril <- predictor(fourteenApril)
sixteenApril <- predictor(fifteenApril)
seventeenApril <- predictor(sixteenApril)
eighteenApril <- predictor(seventeenApril)
nineteenApril <- predictor(eighteenApril)
twentyApril <- predictor(nineteenApril)
twentyoneApril <- predictor(twentyApril)
twentytwoApril <- predictor(twentyoneApril)
twentythreeApril <- predictor(twentytwoApril)
twentyfourApril <- predictor(twentythreeApril)
twentyfiveApril <- predictor(twentyfourApril)


# create vectors to populate the columns
date <- as.Date(c("2020-03-22", "2020-03-23", "2020-03-24", "2020-03-25", '2020-03-26','2020-03-27', '2020-03-28', '2020-03-29', '2020-03-30', '2020-03-31', "2020-04-01", "2020-04-02", "2020-04-03", "2020-04-04", "2020-04-05", "2020-04-06", "2020-04-07", "2020-04-08", "2020-04-09", "2020-04-10", "2020-04-11", "2020-04-12", "2020-04-13", "2020-04-14", "2020-04-15", "2020-04-16", "2020-04-17", "2020-04-18", "2020-04-19", "2020-04-20", "2020-04-21", "2020-04-22", "2020-04-23", "2020-04-24", "2020-04-25"))
estimated_infections_no_action <- c(twentyTwoMarch, twentyThreeMarch, twentyFourMarch, twentyFiveMarch,twentySixMarch, twentySevenMarch, twentyEightMarch, twentyNineMarch, thirtyMarch, thirtyOneMarch, oneApril, twoApril, threeApril, fourApril, fiveApril, sixApril, sevenApril, eightApril, nineApril, tenApril, elevenApril, twelveApril, thirteenApril, fourteenApril, fifteenApril, sixteenApril, seventeenApril, eighteenApril, nineteenApril, twentyApril, twentyoneApril, twentytwoApril, twentythreeApril, twentyfourApril, twentyfiveApril)

# create the data frame
predicted_infections <- data.frame(date, estimated_infections_no_action)

# tidy the estimated_infections column
#predicted_infections <- predicted_infections %>% mutate(estimated_infections=format(estimated_infections, big.mark = ","))

# inspect the data frame
predicted_infections

6. Create another dataframe to estimate the impact of social distancing on the estimate

# create a function that uses a growth rate of 1.125 - half of the 25%. This is the estimate for the not-yet-lockdown that existed up to 23rd March. So, the estimate assumes that the social distancing measures reduced the infection rate by a half.
half_predictor <- function(previous_value) {
    predicted_value <- previous_value * 1.125
    return(predicted_value)
}

# create a function that uses a growth rate of 1.0625 - quarter of the 25%. This is the estimated impact of the lockdown implemented by the UK government on 23rd March (but since the lockdown was announced in the evening, and it would take a full day for its effects to be felt in statistics, I will assume that its effects began on 25th March).
lockdown_predictor <- function(previous_value) {
  predicted_value <- previous_value * 1.0625
  return(predicted_value)
}

# create predictions for each date
twentyTwoMarch <- 1.125 * 360500
twentyThreeMarch <- half_predictor(twentyTwoMarch)
twentyFourMarch <- half_predictor(twentyThreeMarch)
twentyFiveMarch <- lockdown_predictor(twentyFourMarch)
twentySixMarch <- lockdown_predictor(twentyFiveMarch)
twentySevenMarch <- lockdown_predictor(twentySixMarch)
twentyEightMarch <- lockdown_predictor(twentySevenMarch)
twentyNineMarch <- lockdown_predictor(twentyEightMarch)
thirtyMarch <- lockdown_predictor(twentyNineMarch)
thirtyOneMarch <- lockdown_predictor(thirtyMarch)
oneApril <- lockdown_predictor(thirtyOneMarch)
twoApril <- lockdown_predictor(oneApril)
threeApril <- lockdown_predictor(twoApril)
fourApril <- lockdown_predictor(threeApril)
fiveApril <- lockdown_predictor(fourApril)
sixApril <- lockdown_predictor(fiveApril)
sevenApril <- lockdown_predictor(sixApril)
eightApril <- lockdown_predictor(sevenApril)
nineApril <- lockdown_predictor(eightApril)
tenApril <- lockdown_predictor(nineApril)
elevenApril <- lockdown_predictor(tenApril)
twelveApril <- lockdown_predictor(elevenApril)

thirteen_April <- lockdown_predictor(twelveApril)
fourteen_April <- lockdown_predictor(thirteen_April)
fifteen_April <- lockdown_predictor(fourteen_April)
sixteen_April <- lockdown_predictor(fifteen_April)
seventeen_April <- lockdown_predictor(sixteen_April)
eighteen_April <- lockdown_predictor(seventeen_April)
nineteen_April <- lockdown_predictor(eighteen_April)
twenty_April <- lockdown_predictor(nineteen_April)
twentyone_April <- lockdown_predictor(twenty_April)
twentytwo_April <- lockdown_predictor(twentyone_April)
twentythree_April <- lockdown_predictor(twentytwo_April)
twentyfour_April <- lockdown_predictor(twentythree_April)
twentyfive_April <- lockdown_predictor(twentyfour_April)

# create vectors to populate the columns
date <- as.Date(c("2020-03-22", "2020-03-23", "2020-03-24", "2020-03-25", '2020-03-26','2020-03-27', '2020-03-28', '2020-03-29', '2020-03-30', '2020-03-31', "2020-04-01", "2020-04-02", "2020-04-03", "2020-04-04", "2020-04-05", "2020-04-06", "2020-04-07", "2020-04-08", "2020-04-09", "2020-04-10", "2020-04-11", "2020-04-12", "2020-04-13", "2020-04-14", "2020-04-15", "2020-04-16", "2020-04-17", "2020-04-18", "2020-04-19", "2020-04-20", "2020-04-21", "2020-04-22", "2020-04-23", "2020-04-24", "2020-04-25"))
estimated_infections_lockdown <- c(twentyTwoMarch, twentyThreeMarch, twentyFourMarch, twentyFiveMarch,twentySixMarch, twentySevenMarch, twentyEightMarch, twentyNineMarch, thirtyMarch, thirtyOneMarch, oneApril, twoApril, threeApril, fourApril, fiveApril, sixApril, sevenApril, eightApril, nineApril, tenApril, elevenApril, twelveApril, thirteen_April, fourteen_April, fifteen_April, sixteen_April, seventeen_April, eighteen_April, nineteen_April, twenty_April, twentyone_April, twentytwo_April, twentythree_April, twentyfour_April, twentyfive_April)

# create the data frame
lockdown_infection_rates <- data.frame(date, estimated_infections_lockdown)

# tidy the estimated_infections column
#lockdown_infection_rates <- lockdown_infection_rates %>% mutate(estimated_infections_lockdown=format(estimated_infections_lockdown, scientific = FALSE))

# inspect the data frame
lockdown_infection_rates
NA

## 7. Merge the two prediction dataframes

compared_infections <- predicted_infections %>% bind_cols(estimated_infections_lockdown=lockdown_infection_rates$estimated_infections_lockdown)

compared_infections
NA

8. Tidy the data

#compared_infections <- compared_infections %>% mutate(estimated_infections=format(estimated_infections, big.mark = ","))
#compared_infections <- compared_infections %>% mutate(estimated_infections_lockdown=as.numeric(estimated_infections_lockdown))
#compared_infections <- compared_infections %>% mutate(estimated_infections_lockdown=format(estimated_infections_lockdown, big.mark = ","))
compared_infections

The above table shows a huge possible effect of lockdown, but still the number of infections is in seven figures. However, this does not indicate how many people might be infected at any given time. Rather, it estimates how many people might have been infected in total, and so includes people who no longer have the disease (that is, people who have recovered or died).

9. Predicted deaths based on these estimates

Working backwards from these estimates, compare the predicted deaths.

# first, put the columns back to numeric format
#compared_infections_and_deaths <- compared_infections %>% mutate(estimated_infections=as.numeric(estimated_infections))

compared_infections_and_deaths <- compared_infections %>% mutate(estimated_deaths_no_action=0.01*estimated_infections_no_action)
compared_infections_and_deaths <- compared_infections_and_deaths %>% mutate(estimated_deaths_lockdown=0.01*estimated_infections_lockdown)
compared_infections_and_deaths

Note that the estimates_deaths and estimated_deaths_lockdown columns are not estimates for deaths on or up to the date in the relevant row. It is anticipated that deaths would occur some days or weeks after the date given in the table. For example, if the row for 2020-04-01 shows estimated_deaths_lockdown of 8336.703, that doesn’t mean 8336.703 people would have died by 2020-04-01. Rather, that figure would occur around two weeks after 2020-04-01 (so, approximately 2020-04-15). So, this suggests an additional column might be useful (date of predicted deaths) ymd(‘2019-12-01’) %m+% period(“1 month”)

compared_infections_and_deaths_dates <- compared_infections_and_deaths %>% mutate(death_date_14_days=as.Date(date + days(14)))
compared_infections_and_deaths_dates <- compared_infections_and_deaths_dates %>% mutate(death_date_7_days=as.Date(date + days(7)))

# add a column to review the results on a daily basis.
assess <- c("NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA")
compared_infections_and_deaths_dates <- compared_infections_and_deaths_dates %>% mutate(fourteen_day_assessment = assess)

compared_infections_and_deaths_dates <- compared_infections_and_deaths_dates %>% mutate(fourteen_day_assessment=replace(fourteen_day_assessment, death_date_14_days==c("2020-04-05", "2020-04-06", "2020-04-07", "2020-04-08", "2020-04-09", "2020-04-10", "2020-04-11", "2020-04-12", "2020-04-13", "2020-04-14", "2020-04-15", "2020-04-16", "2020-04-17", "2020-04-18", "2020-04-19", "2020-04-20", "2020-04-21", "2020-04-22"), c("As of 2020-04-05, the actual death toll was 4313", "As of 2020-04-06, the actual death toll was 4934", "As of 2020-04-07, the actual death toll was 5373", "As of 2020-04-08, the actual death toll was 6159", "As of 2020-04-09, the actual death toll was 7097", "As of 2020-04-10, the actual death toll was 7978","As of 2020-04-11, the actual death toll was 8958","As of 2020-04-12, the actual death toll was 9875", "As of 2020-04-13, the actual death toll was 10612", "As of 2020-04-14, the actual death toll was 11329", "As of 2020-04-15, the actual death toll was 12107", "As of 2020-04-16, the actual death toll was 12868", "As of 2020-04-17, the actual death toll was 13729", "As of 2020-04-18, the actual death toll was 14576", "As of 2020-04-19, the actual death toll was 15464", "As of 2020-04-20, the actual death toll was 16060", "As of 2020-04-22, the actual death toll was 16509", "As of 2020-04-21, the actual death toll was 17337")))
longer object length is not a multiple of shorter object length
#reorder the columns
new_order <- c("date", "estimated_infections_no_action", "estimated_infections_lockdown", "estimated_deaths_no_action",  "estimated_deaths_lockdown", "death_date_14_days", "fourteen_day_assessment", "death_date_7_days")

compared_infections_and_deaths_dates <- compared_infections_and_deaths_dates[, new_order]

#names <- colnames(compared_infections_and_deaths_dates)
#names
compared_infections_and_deaths_dates

In what ways could these estimates and predictions go wrong? Or, what parts of the data could be inaccurate? * estimate of 1% death rate * estimate of time taken for lockdown to have an effect (I’ve said 14-21 days). Note that death_date_7_days shows the date if it takes 21 days to have an impact. * estimate of daily growth rates for minimal social distancing (1.125) and lockdown (1.0625)

library(ggplot2)
library(scales)
infectionsComparisonLine <- ggplot(compared_infections_and_deaths_dates, aes(x=date)) + geom_line(aes(y=estimated_infections_no_action), col = "steelblue") + geom_line(aes(y=estimated_infections_lockdown), col="darkred") + scale_y_continuous(labels=label_comma()) + geom_text(aes(x=as.Date("2020-04-13"), y = 50000000, label="No action")) + geom_text(x=as.Date("2020-04-13"), y = 5000000, label="Lockdown") + labs(title="Predicted infections (lockdown versus no action)", x='Date', y='Predicted Infections') + theme_classic()
infectionsComparisonLine

NA
deathsComparisonLine <- ggplot(compared_infections_and_deaths_dates, aes(x=death_date_7_days)) + geom_line(aes(y=estimated_deaths_no_action), col = "steelblue") + geom_line(aes(y=estimated_deaths_lockdown), col="darkred") + scale_y_continuous(labels=label_comma()) + geom_text(aes(x=as.Date("2020-04-21"), y = 500000, label="No action")) + geom_text(x=as.Date("2020-04-21"), y = 50000, label="Lockdown") + labs(title="Predicted Deaths (lockdown versus no action)", subtitle="estimates that it takes 3 weeks for measures to impact deaths", x='Date', y='Predicted Deaths') + theme_classic()
deathsComparisonLine

deathsComparisonLine <- ggplot(compared_infections_and_deaths_dates, aes(x=death_date_14_days)) + geom_line(aes(y=estimated_deaths_no_action), col = "steelblue") + geom_line(aes(y=estimated_deaths_lockdown), col="darkred") + scale_y_continuous(labels=label_comma()) + geom_text(aes(x=as.Date("2020-04-28"), y = 500000, label="No action")) + geom_text(x=as.Date("2020-04-28"), y = 50000, label="Lockdown") + labs(title="Predicted Deaths (lockdown versus no action)", subtitle="estimates that it takes 2 weeks for measures to impact deaths", x='Date', y='Predicted Deaths') + theme_classic()
deathsComparisonLine


library(plotly)
casesDeaths <- ggplot(compared_infections_and_deaths_dates, aes(x=estimated_infections_lockdown, y=estimated_deaths_lockdown)) + geom_point()
casesDeaths

interactive <- ggplotly(casesDeaths)

# fig <- interactive %>%
#   plot_ly(
#     x = ~x,
#     y = ~y,
#     frame = ~f,
#     type = 'scatter',
#     mode = 'markers',
#     showlegend = F
#   )
fig <- compared_infections_and_deaths_dates %>% plot_ly(x=~estimated_infections_lockdown, y=~estimated_deaths_lockdown, frame = ~date, type = 'scatter', mode='markers')


# fig <- fig %>% layout(
#     xaxis = list(
#       type = "log"
#     )
#   )
 

fig2 <- fig %>% animation_slider(currentvalue=list(prefix = "Date", font = list(color='red')))
fig2

NA
LS0tCnRpdGxlOiAiQ2FsY3VsYXRpbmcgdGhlIE51bWJlciBvZiBJbmZlY3Rpb25zIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGlzIG5vdGVib29rIGlzIGJhc2VkIG9uIGBjb3ZpZF8xOS5SbWRgLiBJIGNyZWF0ZWQgdGhlIHByZXNlbnQgbm90ZWJvb2sgYmVjYXVzZSB0aGVyZSB3YXMgYWxyZWFkeSB0b28gbXVjaCBpbmZvcm1hdGlvbiBpbiBgY292aWRfMTkuUm1kYC4KCiMjIE1ldGhvZG9sb2d5CiogV2Uga25vdyB0aGUgbnVtYmVyIG9mIHBlb3BsZSBkZWFkLiAKKiBXZSBoYXZlIGVzdGltYXRlcyBvZiBob3cgbWFueSBwZW9wbGUgZGllIGZyb20gdGhlIGRpc2Vhc2UuCiogQXNzdW1lcyB0aGF0IHRoZSBtZWFuIG51bWJlciBvZiBkYXlzIGZyb20gaW5mZWN0aW9uIHRvIGRlYXRoIGlzIDE0IChzZWUgYGNvdmlkX2luZmVjdGlvbl9lc3RpbWF0ZXMyLlJtZGAgZm9yIGVzdGltYXRlcyB1c2luZyAyOCBkYXlzIGFzIHRoZSBhc3N1bXB0aW9uKQoKCiMjIDEuIEltcG9ydCBmaWxlcyBhbmQgcGFja2FnZXMKYGBge3J9CmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShyZWFkcikKbGlicmFyeShsdWJyaWRhdGUpCmRlYXRocyA8LSByZWFkX2NzdignY292aWRfMTlfZGVhdGhzLmNzdicpCmBgYAoKCiMjIDIuIGluc3BlY3QgYW5kIGNsZWFuIHRoZSBkYXRhCmBgYHtyfQoKZGVhdGhzIDwtIGRlYXRocyAlPiUgbXV0YXRlKGluZmVjdGlvbl9kYXRlPURhdGUtZGF5cygxNCkpCmRlYXRocyA8LSBkZWF0aHMgJT4lIHJlbmFtZShkZWF0aF9kYXRlPURhdGUsIGRlYXRocz1gVUsgRGVhdGhzYCkKdWtfZGF0YSA8LSBkZWF0aHMgJT4lIHNlbGVjdCgtYEdsb2JhbCBEZWF0aHNgKQpoZWFkKHVrX2RhdGEpCmBgYAoKCiMjIDMuIEFkZCBlc3RpbWF0ZXMgb2YgaW5mZWN0aW9ucyAodGhyZWUgY29sdW1ucywgc2hvd2luZyBhIGxvdywgbWlkZGxlIGFuZCBhIGhpZ2ggZXN0aW1hdGUpCmBgYHtyfQojYWRkIGNvbHVtbnMgZm9yIHZhcmlvdXMgZXN0aW1hdGVkIGRlYXRoIHJhdGVzICgwLjElLCAwLjUlLCAxJSwgMiUsIDMlKQoKdWtfZGF0YSA8LSB1a19kYXRhICU+JSBtdXRhdGUoZXN0aW1hdGVkX3VrX2Nhc2VzX3RlbnRoPShkZWF0aHMqMTAwMCkpCnVrX2RhdGEgPC0gdWtfZGF0YSAlPiUgbXV0YXRlKGVzdGltYXRlZF91a19jYXNlc19vbmU9KGRlYXRocyoxMDApKQp1a19kYXRhIDwtIHVrX2RhdGEgJT4lIG11dGF0ZShlc3RpbWF0ZWRfdWtfY2FzZXNfdHdvPShkZWF0aHMqNTApKQp1a19kYXRhCgpgYGAKCgojIyA0LiBjbGVhbiB0aGUgZGF0YSBhZ2FpbiAocmVvcmRlciB0aGUgY29sdW1ucykKYGBge3J9CiMgb3JkZXIgc2hvdWxkIGJlIHR3bywgb25lLCB0ZW50aCAoYXMgdGhpcyBzaG93cyB0aGUgbWluLW1heCByYW5nZSBiZXR0ZXIpCmBgYAoKCiMjIDUuIGNyZWF0ZSBhIG5ldyB0YWJsZSB0aGF0IHN0YXJ0cyBhdCAyMm5kIE1hcmNoIChzaW5jZSBgdWtfZGF0YWAgYGluZmVjdGlvbl9kYXRlYCB3ZW50IHVwIHRvIDIxc3QgTWFyY2ggYXQgdGhlIHRpbWUgSSBjcmVhdGVkIHRoaXMgY29kZSkKYGBge3J9CiMgdXNpbmcgb25seSBlc3RpbWF0ZXMgb2YgMSUgZGVhdGggcmF0ZSBhbmQgZ3Jvd3RoIHJhdGUgb2YgZG91YmxpbmcgZXZlcnkgMy00IGRheXMgKHdoaWNoIG1lYW5zIHF1YWRydXBsaW5nIGluIGEgd2VlaykKCnByZWRpY3RvciA8LSBmdW5jdGlvbihwcmV2aW91c192YWx1ZSkgewogICAgcHJlZGljdGVkX3ZhbHVlIDwtIHByZXZpb3VzX3ZhbHVlICogMS4yNQogICAgcmV0dXJuKHByZWRpY3RlZF92YWx1ZSkKICAgIH0KCiMgY3JlYXRlIHByZWRpY3Rpb25zIGZvciBlYWNoIGRhdGUKdHdlbnR5VHdvTWFyY2ggPC0gMS4yNSAqIDM2MDUwMAp0d2VudHlUaHJlZU1hcmNoIDwtIHByZWRpY3Rvcih0d2VudHlUd29NYXJjaCkKdHdlbnR5Rm91ck1hcmNoIDwtIHByZWRpY3Rvcih0d2VudHlUaHJlZU1hcmNoKQp0d2VudHlGaXZlTWFyY2ggPC0gcHJlZGljdG9yKHR3ZW50eUZvdXJNYXJjaCkKdHdlbnR5U2l4TWFyY2ggPC0gcHJlZGljdG9yKHR3ZW50eUZpdmVNYXJjaCkKdHdlbnR5U2V2ZW5NYXJjaCA8LSBwcmVkaWN0b3IodHdlbnR5U2l4TWFyY2gpCnR3ZW50eUVpZ2h0TWFyY2ggPC0gcHJlZGljdG9yKHR3ZW50eVNldmVuTWFyY2gpCnR3ZW50eU5pbmVNYXJjaCA8LSBwcmVkaWN0b3IodHdlbnR5RWlnaHRNYXJjaCkKdGhpcnR5TWFyY2ggPC0gcHJlZGljdG9yKHR3ZW50eU5pbmVNYXJjaCkKdGhpcnR5T25lTWFyY2ggPC0gcHJlZGljdG9yKHRoaXJ0eU1hcmNoKQpvbmVBcHJpbCA8LSBwcmVkaWN0b3IodGhpcnR5T25lTWFyY2gpCnR3b0FwcmlsIDwtIHByZWRpY3RvcihvbmVBcHJpbCkKdGhyZWVBcHJpbCA8LSBwcmVkaWN0b3IodHdvQXByaWwpCmZvdXJBcHJpbCA8LSBwcmVkaWN0b3IodGhyZWVBcHJpbCkKZml2ZUFwcmlsIDwtIHByZWRpY3Rvcihmb3VyQXByaWwpCnNpeEFwcmlsIDwtIHByZWRpY3RvcihmaXZlQXByaWwpCnNldmVuQXByaWwgPC0gcHJlZGljdG9yKHNpeEFwcmlsKQplaWdodEFwcmlsIDwtIHByZWRpY3RvcihzZXZlbkFwcmlsKQpuaW5lQXByaWwgPC0gcHJlZGljdG9yKGVpZ2h0QXByaWwpCnRlbkFwcmlsIDwtIHByZWRpY3RvcihuaW5lQXByaWwpCmVsZXZlbkFwcmlsIDwtIHByZWRpY3Rvcih0ZW5BcHJpbCkKdHdlbHZlQXByaWwgPC0gcHJlZGljdG9yKGVsZXZlbkFwcmlsKQoKdGhpcnRlZW5BcHJpbCA8LSBwcmVkaWN0b3IodHdlbHZlQXByaWwpCmZvdXJ0ZWVuQXByaWwgPC0gcHJlZGljdG9yKHRoaXJ0ZWVuQXByaWwpCmZpZnRlZW5BcHJpbCA8LSBwcmVkaWN0b3IoZm91cnRlZW5BcHJpbCkKc2l4dGVlbkFwcmlsIDwtIHByZWRpY3RvcihmaWZ0ZWVuQXByaWwpCnNldmVudGVlbkFwcmlsIDwtIHByZWRpY3RvcihzaXh0ZWVuQXByaWwpCmVpZ2h0ZWVuQXByaWwgPC0gcHJlZGljdG9yKHNldmVudGVlbkFwcmlsKQpuaW5ldGVlbkFwcmlsIDwtIHByZWRpY3RvcihlaWdodGVlbkFwcmlsKQp0d2VudHlBcHJpbCA8LSBwcmVkaWN0b3IobmluZXRlZW5BcHJpbCkKdHdlbnR5b25lQXByaWwgPC0gcHJlZGljdG9yKHR3ZW50eUFwcmlsKQp0d2VudHl0d29BcHJpbCA8LSBwcmVkaWN0b3IodHdlbnR5b25lQXByaWwpCnR3ZW50eXRocmVlQXByaWwgPC0gcHJlZGljdG9yKHR3ZW50eXR3b0FwcmlsKQp0d2VudHlmb3VyQXByaWwgPC0gcHJlZGljdG9yKHR3ZW50eXRocmVlQXByaWwpCnR3ZW50eWZpdmVBcHJpbCA8LSBwcmVkaWN0b3IodHdlbnR5Zm91ckFwcmlsKQoKCiMgY3JlYXRlIHZlY3RvcnMgdG8gcG9wdWxhdGUgdGhlIGNvbHVtbnMKZGF0ZSA8LSBhcy5EYXRlKGMoIjIwMjAtMDMtMjIiLCAiMjAyMC0wMy0yMyIsICIyMDIwLTAzLTI0IiwgIjIwMjAtMDMtMjUiLCAnMjAyMC0wMy0yNicsJzIwMjAtMDMtMjcnLCAnMjAyMC0wMy0yOCcsICcyMDIwLTAzLTI5JywgJzIwMjAtMDMtMzAnLCAnMjAyMC0wMy0zMScsICIyMDIwLTA0LTAxIiwgIjIwMjAtMDQtMDIiLCAiMjAyMC0wNC0wMyIsICIyMDIwLTA0LTA0IiwgIjIwMjAtMDQtMDUiLCAiMjAyMC0wNC0wNiIsICIyMDIwLTA0LTA3IiwgIjIwMjAtMDQtMDgiLCAiMjAyMC0wNC0wOSIsICIyMDIwLTA0LTEwIiwgIjIwMjAtMDQtMTEiLCAiMjAyMC0wNC0xMiIsICIyMDIwLTA0LTEzIiwgIjIwMjAtMDQtMTQiLCAiMjAyMC0wNC0xNSIsICIyMDIwLTA0LTE2IiwgIjIwMjAtMDQtMTciLCAiMjAyMC0wNC0xOCIsICIyMDIwLTA0LTE5IiwgIjIwMjAtMDQtMjAiLCAiMjAyMC0wNC0yMSIsICIyMDIwLTA0LTIyIiwgIjIwMjAtMDQtMjMiLCAiMjAyMC0wNC0yNCIsICIyMDIwLTA0LTI1IikpCmVzdGltYXRlZF9pbmZlY3Rpb25zX25vX2FjdGlvbiA8LSBjKHR3ZW50eVR3b01hcmNoLCB0d2VudHlUaHJlZU1hcmNoLCB0d2VudHlGb3VyTWFyY2gsIHR3ZW50eUZpdmVNYXJjaCx0d2VudHlTaXhNYXJjaCwgdHdlbnR5U2V2ZW5NYXJjaCwgdHdlbnR5RWlnaHRNYXJjaCwgdHdlbnR5TmluZU1hcmNoLCB0aGlydHlNYXJjaCwgdGhpcnR5T25lTWFyY2gsIG9uZUFwcmlsLCB0d29BcHJpbCwgdGhyZWVBcHJpbCwgZm91ckFwcmlsLCBmaXZlQXByaWwsIHNpeEFwcmlsLCBzZXZlbkFwcmlsLCBlaWdodEFwcmlsLCBuaW5lQXByaWwsIHRlbkFwcmlsLCBlbGV2ZW5BcHJpbCwgdHdlbHZlQXByaWwsIHRoaXJ0ZWVuQXByaWwsIGZvdXJ0ZWVuQXByaWwsIGZpZnRlZW5BcHJpbCwgc2l4dGVlbkFwcmlsLCBzZXZlbnRlZW5BcHJpbCwgZWlnaHRlZW5BcHJpbCwgbmluZXRlZW5BcHJpbCwgdHdlbnR5QXByaWwsIHR3ZW50eW9uZUFwcmlsLCB0d2VudHl0d29BcHJpbCwgdHdlbnR5dGhyZWVBcHJpbCwgdHdlbnR5Zm91ckFwcmlsLCB0d2VudHlmaXZlQXByaWwpCgojIGNyZWF0ZSB0aGUgZGF0YSBmcmFtZQpwcmVkaWN0ZWRfaW5mZWN0aW9ucyA8LSBkYXRhLmZyYW1lKGRhdGUsIGVzdGltYXRlZF9pbmZlY3Rpb25zX25vX2FjdGlvbikKCiMgdGlkeSB0aGUgZXN0aW1hdGVkX2luZmVjdGlvbnMgY29sdW1uCiNwcmVkaWN0ZWRfaW5mZWN0aW9ucyA8LSBwcmVkaWN0ZWRfaW5mZWN0aW9ucyAlPiUgbXV0YXRlKGVzdGltYXRlZF9pbmZlY3Rpb25zPWZvcm1hdChlc3RpbWF0ZWRfaW5mZWN0aW9ucywgYmlnLm1hcmsgPSAiLCIpKQoKIyBpbnNwZWN0IHRoZSBkYXRhIGZyYW1lCnByZWRpY3RlZF9pbmZlY3Rpb25zCmBgYAoKIyMgNi4gQ3JlYXRlIGFub3RoZXIgZGF0YWZyYW1lIHRvIGVzdGltYXRlIHRoZSBpbXBhY3Qgb2Ygc29jaWFsIGRpc3RhbmNpbmcgb24gdGhlIGVzdGltYXRlCmBgYHtyfQojIGNyZWF0ZSBhIGZ1bmN0aW9uIHRoYXQgdXNlcyBhIGdyb3d0aCByYXRlIG9mIDEuMTI1IC0gaGFsZiBvZiB0aGUgMjUlLiBUaGlzIGlzIHRoZSBlc3RpbWF0ZSBmb3IgdGhlIG5vdC15ZXQtbG9ja2Rvd24gdGhhdCBleGlzdGVkIHVwIHRvIDIzcmQgTWFyY2guIFNvLCB0aGUgZXN0aW1hdGUgYXNzdW1lcyB0aGF0IHRoZSBzb2NpYWwgZGlzdGFuY2luZyBtZWFzdXJlcyByZWR1Y2VkIHRoZSBpbmZlY3Rpb24gcmF0ZSBieSBhIGhhbGYuCmhhbGZfcHJlZGljdG9yIDwtIGZ1bmN0aW9uKHByZXZpb3VzX3ZhbHVlKSB7CiAgICBwcmVkaWN0ZWRfdmFsdWUgPC0gcHJldmlvdXNfdmFsdWUgKiAxLjEyNQogICAgcmV0dXJuKHByZWRpY3RlZF92YWx1ZSkKfQoKIyBjcmVhdGUgYSBmdW5jdGlvbiB0aGF0IHVzZXMgYSBncm93dGggcmF0ZSBvZiAxLjA2MjUgLSBxdWFydGVyIG9mIHRoZSAyNSUuIFRoaXMgaXMgdGhlIGVzdGltYXRlZCBpbXBhY3Qgb2YgdGhlIGxvY2tkb3duIGltcGxlbWVudGVkIGJ5IHRoZSBVSyBnb3Zlcm5tZW50IG9uIDIzcmQgTWFyY2ggKGJ1dCBzaW5jZSB0aGUgbG9ja2Rvd24gd2FzIGFubm91bmNlZCBpbiB0aGUgZXZlbmluZywgYW5kIGl0IHdvdWxkIHRha2UgYSBmdWxsIGRheSBmb3IgaXRzIGVmZmVjdHMgdG8gYmUgZmVsdCBpbiBzdGF0aXN0aWNzLCBJIHdpbGwgYXNzdW1lIHRoYXQgaXRzIGVmZmVjdHMgYmVnYW4gb24gMjV0aCBNYXJjaCkuCmxvY2tkb3duX3ByZWRpY3RvciA8LSBmdW5jdGlvbihwcmV2aW91c192YWx1ZSkgewogIHByZWRpY3RlZF92YWx1ZSA8LSBwcmV2aW91c192YWx1ZSAqIDEuMDYyNQogIHJldHVybihwcmVkaWN0ZWRfdmFsdWUpCn0KCiMgY3JlYXRlIHByZWRpY3Rpb25zIGZvciBlYWNoIGRhdGUKdHdlbnR5VHdvTWFyY2ggPC0gMS4xMjUgKiAzNjA1MDAKdHdlbnR5VGhyZWVNYXJjaCA8LSBoYWxmX3ByZWRpY3Rvcih0d2VudHlUd29NYXJjaCkKdHdlbnR5Rm91ck1hcmNoIDwtIGhhbGZfcHJlZGljdG9yKHR3ZW50eVRocmVlTWFyY2gpCnR3ZW50eUZpdmVNYXJjaCA8LSBsb2NrZG93bl9wcmVkaWN0b3IodHdlbnR5Rm91ck1hcmNoKQp0d2VudHlTaXhNYXJjaCA8LSBsb2NrZG93bl9wcmVkaWN0b3IodHdlbnR5Rml2ZU1hcmNoKQp0d2VudHlTZXZlbk1hcmNoIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0d2VudHlTaXhNYXJjaCkKdHdlbnR5RWlnaHRNYXJjaCA8LSBsb2NrZG93bl9wcmVkaWN0b3IodHdlbnR5U2V2ZW5NYXJjaCkKdHdlbnR5TmluZU1hcmNoIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0d2VudHlFaWdodE1hcmNoKQp0aGlydHlNYXJjaCA8LSBsb2NrZG93bl9wcmVkaWN0b3IodHdlbnR5TmluZU1hcmNoKQp0aGlydHlPbmVNYXJjaCA8LSBsb2NrZG93bl9wcmVkaWN0b3IodGhpcnR5TWFyY2gpCm9uZUFwcmlsIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0aGlydHlPbmVNYXJjaCkKdHdvQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKG9uZUFwcmlsKQp0aHJlZUFwcmlsIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0d29BcHJpbCkKZm91ckFwcmlsIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0aHJlZUFwcmlsKQpmaXZlQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKGZvdXJBcHJpbCkKc2l4QXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKGZpdmVBcHJpbCkKc2V2ZW5BcHJpbCA8LSBsb2NrZG93bl9wcmVkaWN0b3Ioc2l4QXByaWwpCmVpZ2h0QXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKHNldmVuQXByaWwpCm5pbmVBcHJpbCA8LSBsb2NrZG93bl9wcmVkaWN0b3IoZWlnaHRBcHJpbCkKdGVuQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKG5pbmVBcHJpbCkKZWxldmVuQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKHRlbkFwcmlsKQp0d2VsdmVBcHJpbCA8LSBsb2NrZG93bl9wcmVkaWN0b3IoZWxldmVuQXByaWwpCgp0aGlydGVlbl9BcHJpbCA8LSBsb2NrZG93bl9wcmVkaWN0b3IodHdlbHZlQXByaWwpCmZvdXJ0ZWVuX0FwcmlsIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0aGlydGVlbl9BcHJpbCkKZmlmdGVlbl9BcHJpbCA8LSBsb2NrZG93bl9wcmVkaWN0b3IoZm91cnRlZW5fQXByaWwpCnNpeHRlZW5fQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKGZpZnRlZW5fQXByaWwpCnNldmVudGVlbl9BcHJpbCA8LSBsb2NrZG93bl9wcmVkaWN0b3Ioc2l4dGVlbl9BcHJpbCkKZWlnaHRlZW5fQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKHNldmVudGVlbl9BcHJpbCkKbmluZXRlZW5fQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKGVpZ2h0ZWVuX0FwcmlsKQp0d2VudHlfQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKG5pbmV0ZWVuX0FwcmlsKQp0d2VudHlvbmVfQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKHR3ZW50eV9BcHJpbCkKdHdlbnR5dHdvX0FwcmlsIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0d2VudHlvbmVfQXByaWwpCnR3ZW50eXRocmVlX0FwcmlsIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0d2VudHl0d29fQXByaWwpCnR3ZW50eWZvdXJfQXByaWwgPC0gbG9ja2Rvd25fcHJlZGljdG9yKHR3ZW50eXRocmVlX0FwcmlsKQp0d2VudHlmaXZlX0FwcmlsIDwtIGxvY2tkb3duX3ByZWRpY3Rvcih0d2VudHlmb3VyX0FwcmlsKQoKIyBjcmVhdGUgdmVjdG9ycyB0byBwb3B1bGF0ZSB0aGUgY29sdW1ucwpkYXRlIDwtIGFzLkRhdGUoYygiMjAyMC0wMy0yMiIsICIyMDIwLTAzLTIzIiwgIjIwMjAtMDMtMjQiLCAiMjAyMC0wMy0yNSIsICcyMDIwLTAzLTI2JywnMjAyMC0wMy0yNycsICcyMDIwLTAzLTI4JywgJzIwMjAtMDMtMjknLCAnMjAyMC0wMy0zMCcsICcyMDIwLTAzLTMxJywgIjIwMjAtMDQtMDEiLCAiMjAyMC0wNC0wMiIsICIyMDIwLTA0LTAzIiwgIjIwMjAtMDQtMDQiLCAiMjAyMC0wNC0wNSIsICIyMDIwLTA0LTA2IiwgIjIwMjAtMDQtMDciLCAiMjAyMC0wNC0wOCIsICIyMDIwLTA0LTA5IiwgIjIwMjAtMDQtMTAiLCAiMjAyMC0wNC0xMSIsICIyMDIwLTA0LTEyIiwgIjIwMjAtMDQtMTMiLCAiMjAyMC0wNC0xNCIsICIyMDIwLTA0LTE1IiwgIjIwMjAtMDQtMTYiLCAiMjAyMC0wNC0xNyIsICIyMDIwLTA0LTE4IiwgIjIwMjAtMDQtMTkiLCAiMjAyMC0wNC0yMCIsICIyMDIwLTA0LTIxIiwgIjIwMjAtMDQtMjIiLCAiMjAyMC0wNC0yMyIsICIyMDIwLTA0LTI0IiwgIjIwMjAtMDQtMjUiKSkKZXN0aW1hdGVkX2luZmVjdGlvbnNfbG9ja2Rvd24gPC0gYyh0d2VudHlUd29NYXJjaCwgdHdlbnR5VGhyZWVNYXJjaCwgdHdlbnR5Rm91ck1hcmNoLCB0d2VudHlGaXZlTWFyY2gsdHdlbnR5U2l4TWFyY2gsIHR3ZW50eVNldmVuTWFyY2gsIHR3ZW50eUVpZ2h0TWFyY2gsIHR3ZW50eU5pbmVNYXJjaCwgdGhpcnR5TWFyY2gsIHRoaXJ0eU9uZU1hcmNoLCBvbmVBcHJpbCwgdHdvQXByaWwsIHRocmVlQXByaWwsIGZvdXJBcHJpbCwgZml2ZUFwcmlsLCBzaXhBcHJpbCwgc2V2ZW5BcHJpbCwgZWlnaHRBcHJpbCwgbmluZUFwcmlsLCB0ZW5BcHJpbCwgZWxldmVuQXByaWwsIHR3ZWx2ZUFwcmlsLCB0aGlydGVlbl9BcHJpbCwgZm91cnRlZW5fQXByaWwsIGZpZnRlZW5fQXByaWwsIHNpeHRlZW5fQXByaWwsIHNldmVudGVlbl9BcHJpbCwgZWlnaHRlZW5fQXByaWwsIG5pbmV0ZWVuX0FwcmlsLCB0d2VudHlfQXByaWwsIHR3ZW50eW9uZV9BcHJpbCwgdHdlbnR5dHdvX0FwcmlsLCB0d2VudHl0aHJlZV9BcHJpbCwgdHdlbnR5Zm91cl9BcHJpbCwgdHdlbnR5Zml2ZV9BcHJpbCkKCiMgY3JlYXRlIHRoZSBkYXRhIGZyYW1lCmxvY2tkb3duX2luZmVjdGlvbl9yYXRlcyA8LSBkYXRhLmZyYW1lKGRhdGUsIGVzdGltYXRlZF9pbmZlY3Rpb25zX2xvY2tkb3duKQoKIyB0aWR5IHRoZSBlc3RpbWF0ZWRfaW5mZWN0aW9ucyBjb2x1bW4KI2xvY2tkb3duX2luZmVjdGlvbl9yYXRlcyA8LSBsb2NrZG93bl9pbmZlY3Rpb25fcmF0ZXMgJT4lIG11dGF0ZShlc3RpbWF0ZWRfaW5mZWN0aW9uc19sb2NrZG93bj1mb3JtYXQoZXN0aW1hdGVkX2luZmVjdGlvbnNfbG9ja2Rvd24sIHNjaWVudGlmaWMgPSBGQUxTRSkpCgojIGluc3BlY3QgdGhlIGRhdGEgZnJhbWUKbG9ja2Rvd25faW5mZWN0aW9uX3JhdGVzCgpgYGAKCiAjIyA3LiBNZXJnZSB0aGUgdHdvIHByZWRpY3Rpb24gZGF0YWZyYW1lcwpgYGB7cn0KY29tcGFyZWRfaW5mZWN0aW9ucyA8LSBwcmVkaWN0ZWRfaW5mZWN0aW9ucyAlPiUgYmluZF9jb2xzKGVzdGltYXRlZF9pbmZlY3Rpb25zX2xvY2tkb3duPWxvY2tkb3duX2luZmVjdGlvbl9yYXRlcyRlc3RpbWF0ZWRfaW5mZWN0aW9uc19sb2NrZG93bikKCmNvbXBhcmVkX2luZmVjdGlvbnMKCmBgYAoKIyMgOC4gVGlkeSB0aGUgZGF0YQpgYGB7cn0KI2NvbXBhcmVkX2luZmVjdGlvbnMgPC0gY29tcGFyZWRfaW5mZWN0aW9ucyAlPiUgbXV0YXRlKGVzdGltYXRlZF9pbmZlY3Rpb25zPWZvcm1hdChlc3RpbWF0ZWRfaW5mZWN0aW9ucywgYmlnLm1hcmsgPSAiLCIpKQojY29tcGFyZWRfaW5mZWN0aW9ucyA8LSBjb21wYXJlZF9pbmZlY3Rpb25zICU+JSBtdXRhdGUoZXN0aW1hdGVkX2luZmVjdGlvbnNfbG9ja2Rvd249YXMubnVtZXJpYyhlc3RpbWF0ZWRfaW5mZWN0aW9uc19sb2NrZG93bikpCiNjb21wYXJlZF9pbmZlY3Rpb25zIDwtIGNvbXBhcmVkX2luZmVjdGlvbnMgJT4lIG11dGF0ZShlc3RpbWF0ZWRfaW5mZWN0aW9uc19sb2NrZG93bj1mb3JtYXQoZXN0aW1hdGVkX2luZmVjdGlvbnNfbG9ja2Rvd24sIGJpZy5tYXJrID0gIiwiKSkKY29tcGFyZWRfaW5mZWN0aW9ucwpgYGAKClRoZSBhYm92ZSB0YWJsZSBzaG93cyBhIGh1Z2UgcG9zc2libGUgZWZmZWN0IG9mIGxvY2tkb3duLCBidXQgc3RpbGwgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zIGlzIGluIHNldmVuIGZpZ3VyZXMuIEhvd2V2ZXIsIHRoaXMgZG9lcyBub3QgaW5kaWNhdGUgaG93IG1hbnkgcGVvcGxlIG1pZ2h0IGJlIGluZmVjdGVkIGF0IGFueSBnaXZlbiB0aW1lLiBSYXRoZXIsIGl0IGVzdGltYXRlcyBob3cgbWFueSBwZW9wbGUgbWlnaHQgaGF2ZSBiZWVuIGluZmVjdGVkIGluIHRvdGFsLCBhbmQgc28gaW5jbHVkZXMgcGVvcGxlIHdobyBubyBsb25nZXIgaGF2ZSB0aGUgZGlzZWFzZSAodGhhdCBpcywgcGVvcGxlIHdobyBoYXZlIHJlY292ZXJlZCBvciBkaWVkKS4KCiMjIDkuIFByZWRpY3RlZCBkZWF0aHMgYmFzZWQgb24gdGhlc2UgZXN0aW1hdGVzCldvcmtpbmcgYmFja3dhcmRzIGZyb20gdGhlc2UgZXN0aW1hdGVzLCBjb21wYXJlIHRoZSBwcmVkaWN0ZWQgZGVhdGhzLiAKYGBge3J9CiMgZmlyc3QsIHB1dCB0aGUgY29sdW1ucyBiYWNrIHRvIG51bWVyaWMgZm9ybWF0CiNjb21wYXJlZF9pbmZlY3Rpb25zX2FuZF9kZWF0aHMgPC0gY29tcGFyZWRfaW5mZWN0aW9ucyAlPiUgbXV0YXRlKGVzdGltYXRlZF9pbmZlY3Rpb25zPWFzLm51bWVyaWMoZXN0aW1hdGVkX2luZmVjdGlvbnMpKQoKY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzIDwtIGNvbXBhcmVkX2luZmVjdGlvbnMgJT4lIG11dGF0ZShlc3RpbWF0ZWRfZGVhdGhzX25vX2FjdGlvbj0wLjAxKmVzdGltYXRlZF9pbmZlY3Rpb25zX25vX2FjdGlvbikKY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzIDwtIGNvbXBhcmVkX2luZmVjdGlvbnNfYW5kX2RlYXRocyAlPiUgbXV0YXRlKGVzdGltYXRlZF9kZWF0aHNfbG9ja2Rvd249MC4wMSplc3RpbWF0ZWRfaW5mZWN0aW9uc19sb2NrZG93bikKY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzCmBgYApOb3RlIHRoYXQgdGhlIGBlc3RpbWF0ZXNfZGVhdGhzYCBhbmQgYGVzdGltYXRlZF9kZWF0aHNfbG9ja2Rvd25gIGNvbHVtbnMgYXJlIG5vdCBlc3RpbWF0ZXMgZm9yIGRlYXRocyBvbiBvciB1cCB0byB0aGUgZGF0ZSBpbiB0aGUgcmVsZXZhbnQgcm93LiBJdCBpcyBhbnRpY2lwYXRlZCB0aGF0IGRlYXRocyB3b3VsZCBvY2N1ciBzb21lIGRheXMgb3Igd2Vla3MgYWZ0ZXIgdGhlIGRhdGUgZ2l2ZW4gaW4gdGhlIHRhYmxlLiBGb3IgZXhhbXBsZSwgaWYgdGhlIHJvdyBmb3IgMjAyMC0wNC0wMSBzaG93cyBgZXN0aW1hdGVkX2RlYXRoc19sb2NrZG93bmAgb2YgODMzNi43MDMsIHRoYXQgZG9lc24ndCBtZWFuIDgzMzYuNzAzIHBlb3BsZSB3b3VsZCBoYXZlIGRpZWQgYnkgMjAyMC0wNC0wMS4gUmF0aGVyLCB0aGF0IGZpZ3VyZSB3b3VsZCBvY2N1ciBhcm91bmQgdHdvIHdlZWtzIGFmdGVyIDIwMjAtMDQtMDEgKHNvLCBhcHByb3hpbWF0ZWx5IDIwMjAtMDQtMTUpLiBTbywgdGhpcyBzdWdnZXN0cyBhbiBhZGRpdGlvbmFsIGNvbHVtbiBtaWdodCBiZSB1c2VmdWwgKGRhdGUgb2YgcHJlZGljdGVkIGRlYXRocykKeW1kKCcyMDE5LTEyLTAxJykgJW0rJSBwZXJpb2QoIjEgbW9udGgiKQoKYGBge3J9CmNvbXBhcmVkX2luZmVjdGlvbnNfYW5kX2RlYXRoc19kYXRlcyA8LSBjb21wYXJlZF9pbmZlY3Rpb25zX2FuZF9kZWF0aHMgJT4lIG11dGF0ZShkZWF0aF9kYXRlXzE0X2RheXM9YXMuRGF0ZShkYXRlICsgZGF5cygxNCkpKQpjb21wYXJlZF9pbmZlY3Rpb25zX2FuZF9kZWF0aHNfZGF0ZXMgPC0gY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzX2RhdGVzICU+JSBtdXRhdGUoZGVhdGhfZGF0ZV83X2RheXM9YXMuRGF0ZShkYXRlICsgZGF5cyg3KSkpCgojIGFkZCBhIGNvbHVtbiB0byByZXZpZXcgdGhlIHJlc3VsdHMgb24gYSBkYWlseSBiYXNpcy4KYXNzZXNzIDwtIGMoIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIiwgIk5BIikKY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzX2RhdGVzIDwtIGNvbXBhcmVkX2luZmVjdGlvbnNfYW5kX2RlYXRoc19kYXRlcyAlPiUgbXV0YXRlKGZvdXJ0ZWVuX2RheV9hc3Nlc3NtZW50ID0gYXNzZXNzKQoKY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzX2RhdGVzIDwtIGNvbXBhcmVkX2luZmVjdGlvbnNfYW5kX2RlYXRoc19kYXRlcyAlPiUgbXV0YXRlKGZvdXJ0ZWVuX2RheV9hc3Nlc3NtZW50PXJlcGxhY2UoZm91cnRlZW5fZGF5X2Fzc2Vzc21lbnQsIGRlYXRoX2RhdGVfMTRfZGF5cz09YygiMjAyMC0wNC0wNSIsICIyMDIwLTA0LTA2IiwgIjIwMjAtMDQtMDciLCAiMjAyMC0wNC0wOCIsICIyMDIwLTA0LTA5IiwgIjIwMjAtMDQtMTAiLCAiMjAyMC0wNC0xMSIsICIyMDIwLTA0LTEyIiwgIjIwMjAtMDQtMTMiLCAiMjAyMC0wNC0xNCIsICIyMDIwLTA0LTE1IiwgIjIwMjAtMDQtMTYiLCAiMjAyMC0wNC0xNyIsICIyMDIwLTA0LTE4IiwgIjIwMjAtMDQtMTkiLCAiMjAyMC0wNC0yMCIsICIyMDIwLTA0LTIxIiwgIjIwMjAtMDQtMjIiKSwgYygiQXMgb2YgMjAyMC0wNC0wNSwgdGhlIGFjdHVhbCBkZWF0aCB0b2xsIHdhcyA0MzEzIiwgIkFzIG9mIDIwMjAtMDQtMDYsIHRoZSBhY3R1YWwgZGVhdGggdG9sbCB3YXMgNDkzNCIsICJBcyBvZiAyMDIwLTA0LTA3LCB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgd2FzIDUzNzMiLCAiQXMgb2YgMjAyMC0wNC0wOCwgdGhlIGFjdHVhbCBkZWF0aCB0b2xsIHdhcyA2MTU5IiwgIkFzIG9mIDIwMjAtMDQtMDksIHRoZSBhY3R1YWwgZGVhdGggdG9sbCB3YXMgNzA5NyIsICJBcyBvZiAyMDIwLTA0LTEwLCB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgd2FzIDc5NzgiLCJBcyBvZiAyMDIwLTA0LTExLCB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgd2FzIDg5NTgiLCJBcyBvZiAyMDIwLTA0LTEyLCB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgd2FzIDk4NzUiLCAiQXMgb2YgMjAyMC0wNC0xMywgdGhlIGFjdHVhbCBkZWF0aCB0b2xsIHdhcyAxMDYxMiIsICJBcyBvZiAyMDIwLTA0LTE0LCB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgd2FzIDExMzI5IiwgIkFzIG9mIDIwMjAtMDQtMTUsIHRoZSBhY3R1YWwgZGVhdGggdG9sbCB3YXMgMTIxMDciLCAiQXMgb2YgMjAyMC0wNC0xNiwgdGhlIGFjdHVhbCBkZWF0aCB0b2xsIHdhcyAxMjg2OCIsICJBcyBvZiAyMDIwLTA0LTE3LCB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgd2FzIDEzNzI5IiwgIkFzIG9mIDIwMjAtMDQtMTgsIHRoZSBhY3R1YWwgZGVhdGggdG9sbCB3YXMgMTQ1NzYiLCAiQXMgb2YgMjAyMC0wNC0xOSwgdGhlIGFjdHVhbCBkZWF0aCB0b2xsIHdhcyAxNTQ2NCIsICJBcyBvZiAyMDIwLTA0LTIwLCB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgd2FzIDE2MDYwIiwgIkFzIG9mIDIwMjAtMDQtMjIsIHRoZSBhY3R1YWwgZGVhdGggdG9sbCB3YXMgMTY1MDkiLCAiQXMgb2YgMjAyMC0wNC0yMSwgdGhlIGFjdHVhbCBkZWF0aCB0b2xsIHdhcyAxNzMzNyIpKSkKCiNyZW9yZGVyIHRoZSBjb2x1bW5zCm5ld19vcmRlciA8LSBjKCJkYXRlIiwgImVzdGltYXRlZF9pbmZlY3Rpb25zX25vX2FjdGlvbiIsICJlc3RpbWF0ZWRfaW5mZWN0aW9uc19sb2NrZG93biIsICJlc3RpbWF0ZWRfZGVhdGhzX25vX2FjdGlvbiIsICAiZXN0aW1hdGVkX2RlYXRoc19sb2NrZG93biIsICJkZWF0aF9kYXRlXzE0X2RheXMiLCAiZm91cnRlZW5fZGF5X2Fzc2Vzc21lbnQiLCAiZGVhdGhfZGF0ZV83X2RheXMiKQoKY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzX2RhdGVzIDwtIGNvbXBhcmVkX2luZmVjdGlvbnNfYW5kX2RlYXRoc19kYXRlc1ssIG5ld19vcmRlcl0KCiNuYW1lcyA8LSBjb2xuYW1lcyhjb21wYXJlZF9pbmZlY3Rpb25zX2FuZF9kZWF0aHNfZGF0ZXMpCiNuYW1lcwpjb21wYXJlZF9pbmZlY3Rpb25zX2FuZF9kZWF0aHNfZGF0ZXMKYGBgCgpJbiB3aGF0IHdheXMgY291bGQgdGhlc2UgZXN0aW1hdGVzIGFuZCBwcmVkaWN0aW9ucyBnbyB3cm9uZz8gT3IsIHdoYXQgcGFydHMgb2YgdGhlIGRhdGEgY291bGQgYmUgaW5hY2N1cmF0ZT8KKiBlc3RpbWF0ZSBvZiAxJSBkZWF0aCByYXRlIAoqIGVzdGltYXRlIG9mIHRpbWUgdGFrZW4gZm9yIGxvY2tkb3duIHRvIGhhdmUgYW4gZWZmZWN0IChJJ3ZlIHNhaWQgMTQtMjEgZGF5cykuIE5vdGUgdGhhdCBgZGVhdGhfZGF0ZV83X2RheXNgIHNob3dzIHRoZSBkYXRlIGlmIGl0IHRha2VzIDIxIGRheXMgdG8gaGF2ZSBhbiBpbXBhY3QuIAoqIGVzdGltYXRlIG9mIGRhaWx5IGdyb3d0aCByYXRlcyBmb3IgbWluaW1hbCBzb2NpYWwgZGlzdGFuY2luZyAoMS4xMjUpIGFuZCBsb2NrZG93biAoMS4wNjI1KQoKKiB1cGRhdGUgNnRoIEFwcmlsIDIwMjAgLSBpdCBsb29rcyBsaWtlIG15IHByZWRpY3Rpb25zIG1heSBiZSBhIGRheSBvciB0d28gb3V0IG9mIHN5bmNoIHdpdGggdGhlIHN0YXRzLiBJdCdzIGhhcmQgdG8gdGVsbCwgYXMgdGhlIG51bWJlciBmb3IgbG9ja2Rvd24gYW5kIG5vIGFjdGlvbiBhcmUgZmFpcmx5IHNpbWlsYXIgYXQgdGhpcyBwb2ludC4gVGhpcyBtZWFucyB0aGF0IGl0IGNhbiBiZSBkaWZmaWN1bHQgdG8gbWFrZSBhbiBhc3Nlc3NtZW50OiBpZiB0aGUgYWN0dWFsIGRlYXRoIHRvbGwgaXMgbG93ZXIgdGhhbiB0aGUgZXN0aW1hdGVkX2RlYXRoc19ub19hY3Rpb24gY29sdW1uLCBpcyB0aGF0IGR1ZSB0byB0aGUgbG9ja2Rvd24gb3IgdGhlIGZhY3QgdGhhdCBpdCBpcyBhIGRheSBvciB0d28gYmVoaW5kPyBIb3dldmVyLCBieSBhcm91bmQgMTB0aCBBcHJpbCB0aGVyZSBzaG91bGQgYmUgYSBjbGVhcmVyIHBpY3R1cmUuIAoKKiB1cGRhdGUgMTB0aCBBcHJpbCAyMDIwIC0gaXQgbm93IGxvb2tzIGxpa2UgbXkgcHJlZGljdGlvbnMgbWlnaHQgYmUgMyBvciA0IGRheXMgb3V0IG9mIHN5bmNoIHdpdGggdGhlIHN0YXRzLiBMb29rIGF0IHRoZSBgZGVhdGhfZGF0ZV8xNF9kYXlzYCBjb2x1bW4sIHRoZW4gYWRkIDQgZGF5cy4gVGhlbiBsb29rIGF0IHRoZSBgZXN0aW1hdGVkX2RlYXRoc19sb2NrZG93bmAgY29sdW1uLiBUaGlzIHNlZW1zIHRvIGJlIGNsb3NlciB0byB0aGUgYWN0dWFsIGRlYXRoIHRvbGwuIAoqIHVwZGF0ZSAxMXRoIEFwcmlsIDIwMjA6IGhvc3BpdGFsIGRlYXRocyB2ZXJzdXMgdG90YWwgZGVhdGhzLiBNeSBmaWd1cmVzIGFyZSBmb3IgdG90YWwgZGVhdGhzLCBidXQgdGhlIFVLIHByb3ZpZGVzIGZpZ3VyZXMgZm9yIGhvc3BpdGFsIGRlYXRocy4gT25lIGVzdGltYXRlIEkgc2F3IHdhcyB0aGF0IHRoZXJlIHdlcmUgb3ZlciA4MDAwIGRlYXRocyBpbiBob3NwaXRhbCwgcGx1cyBhbiBhZGRpdGlvbmFsIDEwMDAgaW4gY2FyZSBob21lcyB0aGF0IHdlcmUgbm90IGluY2x1ZGVkIGluIHRoZSBVSyBmaWd1cmVzLiBJJ20gbm90IHN1cmUgd2hldGhlciBvciBub3QgdGhlIFdITyBmaWd1cmVzIGNvdmVyIG9ubHkgaG9zcGl0YWwgZGVhdGhzLCBidXQgaWYgdGhleSBkbyB0aGVuIGl0IHdvdWxkIGhhdmUgYW4gaW1wYWN0IG9uIG15IHByZWRpY3Rpb25zLgoqIHVwZGF0ZSAxMnRoIEFwcmlsIDIwMjAgLSBpdCBub3cgbG9va3MgbGlrZSBteSBwcmVkaWN0aW9ucyBhcmUgNS02IGRheXMgb3V0IG9mIHN5bmNoIHdpdGggdGhlIHN0YXRzLiBTbywgbG9vayBhdCB0aGUgYGRlYXRoX2RhdGVfMTRfZGF5c2AgY29sdW1uLCB0aGVuIGFkZCA1IG9yIDYgZGF5cy4gCiogdXBkYXRlIDEzdGggQXByaWwgMjAyMCAtIHRoZSBsYXRlc3QgZmlndXJlcyBmcm9tIHRoZSBbT2ZmaWNlIGZvciBOYXRpb25hbCBTdGF0aXN0aWNzXShodHRwczovL3d3dy5vbnMuZ292LnVrL3Blb3BsZXBvcHVsYXRpb25hbmRjb21tdW5pdHkvYmlydGhzZGVhdGhzYW5kbWFycmlhZ2VzL2RlYXRocy9idWxsZXRpbnMvZGVhdGhzcmVnaXN0ZXJlZHdlZWtseWluZW5nbGFuZGFuZHdhbGVzcHJvdmlzaW9uYWwvd2Vla2VuZGluZzNhcHJpbDIwMjApIHN1Z2dlc3QgdGhhdCAtIGluIEVuZ2xhbmQgYW5kIFdhbGVzLCBhdCBsZWFzdCAtIGRlYXRocyBvdXRzaWRlIGhvc3BpdGFscyBhY2NvdW50IGZvciBhcm91bmQgMTAlIG9mIGFsbCBDb3ZpZC0xOS1yZWxhdGVkIGRlYXRocy4gV2hpbHN0IEkgZG8gbm90IGhhdmUgdGhlIG5vbi1ob3NwaXRhbCBmaWd1cmVzIGZvciBTY290bGFuZCBvciBOb3J0aGVybiBJcmVsYW5kLCBJIGhhdmUgbm8gcmVhc29uIHRvIGJlbGlldmUgdGhleSB3b3VsZCBiZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIEVuZ2xhbmQgYW5kIFdhbGVzLiBTbywgSSB3aWxsIGFzc3VtZSB0aGF0IDEwJSBvZiBhbGwgQ292aWQtMTktcmVsYXRlZCBkZWF0aHMgaW4gdGhlIFVLIGhhcHBlbiBvdXRzaWRlIG9mIGhvc3BpdGFscy4gVGhpcyBoYXMgYW4gaW1wYWN0IG9uIGhvdyBvbmUgcmVhZHMgdGhlIGZpZ3VyZXMgaW4gbXkgcHJvamVjdC4gVGhlIGZpZ3VyZXMgSSB1c2UgaW4gdGhpcyBwcm9qZWN0IGFyZSBmcm9tIHRoZSBXSE8sIHdoaWNoIGNvdW50cyBob3NwaXRhbCBkZWF0aHMgb25seS4gVGhlcmVmb3JlLCBmb3IgYW55IGdpdmVuIGRhdGUsIHRoZSBudW1iZXIgb2YgZGVhdGhzIGluIG15IGRhdGFzZXRzIHNob3VsZCBiZSBjb25zaWRlcmVkIHRvIGJlIG9ubHkgOTAlIG9mIHRoZSB0cnVlIHRvdGFsLiBGb3IgaW5zdGFuY2UsIHdoZXJlIG15IGRhdGFzZXRzIHN0YXRlIHRoYXQgdGhlIGRlYXRoIHRvbGwgb24gMTF0aCBBcHJpbCB3YXMgODk1OCwgd2UgY2FuIGVzdGltYXRlIHRoYXQgdGhlIHRydWUgZGVhdGggdG9sbCB3YXMgYWN0dWFsbHkgYXJvdW5kIDEwLDAwMC4KKiB1cGRhdGUgMTd0aCBBcHJpbCAtIHRoZSBmaWd1cmVzIGFyZSA2LTcgZGF5cyBvdXQuCgpgYGB7ciwgZmlnLndpZHRoPSA5LjUsIGZpZy5oZWlnaHQ9Nn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHNjYWxlcykKaW5mZWN0aW9uc0NvbXBhcmlzb25MaW5lIDwtIGdncGxvdChjb21wYXJlZF9pbmZlY3Rpb25zX2FuZF9kZWF0aHNfZGF0ZXMsIGFlcyh4PWRhdGUpKSArIGdlb21fbGluZShhZXMoeT1lc3RpbWF0ZWRfaW5mZWN0aW9uc19ub19hY3Rpb24pLCBjb2wgPSAic3RlZWxibHVlIikgKyBnZW9tX2xpbmUoYWVzKHk9ZXN0aW1hdGVkX2luZmVjdGlvbnNfbG9ja2Rvd24pLCBjb2w9ImRhcmtyZWQiKSArIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9bGFiZWxfY29tbWEoKSkgKyBnZW9tX3RleHQoYWVzKHg9YXMuRGF0ZSgiMjAyMC0wNC0xMyIpLCB5ID0gNTAwMDAwMDAsIGxhYmVsPSJObyBhY3Rpb24iKSkgKyBnZW9tX3RleHQoeD1hcy5EYXRlKCIyMDIwLTA0LTEzIiksIHkgPSA1MDAwMDAwLCBsYWJlbD0iTG9ja2Rvd24iKSArIGxhYnModGl0bGU9IlByZWRpY3RlZCBpbmZlY3Rpb25zIChsb2NrZG93biB2ZXJzdXMgbm8gYWN0aW9uKSIsIHg9J0RhdGUnLCB5PSdQcmVkaWN0ZWQgSW5mZWN0aW9ucycpICsgdGhlbWVfY2xhc3NpYygpCmluZmVjdGlvbnNDb21wYXJpc29uTGluZQogCmBgYAoKYGBge3IsIGZpZy53aWR0aD0gOS41LCBmaWcuaGVpZ2h0PTZ9CmRlYXRoc0NvbXBhcmlzb25MaW5lIDwtIGdncGxvdChjb21wYXJlZF9pbmZlY3Rpb25zX2FuZF9kZWF0aHNfZGF0ZXMsIGFlcyh4PWRlYXRoX2RhdGVfN19kYXlzKSkgKyBnZW9tX2xpbmUoYWVzKHk9ZXN0aW1hdGVkX2RlYXRoc19ub19hY3Rpb24pLCBjb2wgPSAic3RlZWxibHVlIikgKyBnZW9tX2xpbmUoYWVzKHk9ZXN0aW1hdGVkX2RlYXRoc19sb2NrZG93biksIGNvbD0iZGFya3JlZCIpICsgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1sYWJlbF9jb21tYSgpKSArIGdlb21fdGV4dChhZXMoeD1hcy5EYXRlKCIyMDIwLTA0LTIxIiksIHkgPSA1MDAwMDAsIGxhYmVsPSJObyBhY3Rpb24iKSkgKyBnZW9tX3RleHQoeD1hcy5EYXRlKCIyMDIwLTA0LTIxIiksIHkgPSA1MDAwMCwgbGFiZWw9IkxvY2tkb3duIikgKyBsYWJzKHRpdGxlPSJQcmVkaWN0ZWQgRGVhdGhzIChsb2NrZG93biB2ZXJzdXMgbm8gYWN0aW9uKSIsIHN1YnRpdGxlPSJlc3RpbWF0ZXMgdGhhdCBpdCB0YWtlcyAzIHdlZWtzIGZvciBtZWFzdXJlcyB0byBpbXBhY3QgZGVhdGhzIiwgeD0nRGF0ZScsIHk9J1ByZWRpY3RlZCBEZWF0aHMnKSArIHRoZW1lX2NsYXNzaWMoKQpkZWF0aHNDb21wYXJpc29uTGluZQpgYGAKCmBgYHtyfQpkZWF0aHNDb21wYXJpc29uTGluZSA8LSBnZ3Bsb3QoY29tcGFyZWRfaW5mZWN0aW9uc19hbmRfZGVhdGhzX2RhdGVzLCBhZXMoeD1kZWF0aF9kYXRlXzE0X2RheXMpKSArIGdlb21fbGluZShhZXMoeT1lc3RpbWF0ZWRfZGVhdGhzX25vX2FjdGlvbiksIGNvbCA9ICJzdGVlbGJsdWUiKSArIGdlb21fbGluZShhZXMoeT1lc3RpbWF0ZWRfZGVhdGhzX2xvY2tkb3duKSwgY29sPSJkYXJrcmVkIikgKyBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPWxhYmVsX2NvbW1hKCkpICsgZ2VvbV90ZXh0KGFlcyh4PWFzLkRhdGUoIjIwMjAtMDQtMjgiKSwgeSA9IDUwMDAwMCwgbGFiZWw9Ik5vIGFjdGlvbiIpKSArIGdlb21fdGV4dCh4PWFzLkRhdGUoIjIwMjAtMDQtMjgiKSwgeSA9IDUwMDAwLCBsYWJlbD0iTG9ja2Rvd24iKSArIGxhYnModGl0bGU9IlByZWRpY3RlZCBEZWF0aHMgKGxvY2tkb3duIHZlcnN1cyBubyBhY3Rpb24pIiwgc3VidGl0bGU9ImVzdGltYXRlcyB0aGF0IGl0IHRha2VzIDIgd2Vla3MgZm9yIG1lYXN1cmVzIHRvIGltcGFjdCBkZWF0aHMiLCB4PSdEYXRlJywgeT0nUHJlZGljdGVkIERlYXRocycpICsgdGhlbWVfY2xhc3NpYygpCmRlYXRoc0NvbXBhcmlzb25MaW5lCmBgYAoKYGBge3IsIGZpZy53aWR0aD0gOS41LCBmaWcuaGVpZ2h0PTZ9CgpsaWJyYXJ5KHBsb3RseSkKY2FzZXNEZWF0aHMgPC0gZ2dwbG90KGNvbXBhcmVkX2luZmVjdGlvbnNfYW5kX2RlYXRoc19kYXRlcywgYWVzKHg9ZXN0aW1hdGVkX2luZmVjdGlvbnNfbG9ja2Rvd24sIHk9ZXN0aW1hdGVkX2RlYXRoc19sb2NrZG93bikpICsgZ2VvbV9wb2ludCgpCmNhc2VzRGVhdGhzCmludGVyYWN0aXZlIDwtIGdncGxvdGx5KGNhc2VzRGVhdGhzKQoKIyBmaWcgPC0gaW50ZXJhY3RpdmUgJT4lCiMgICBwbG90X2x5KAojICAgICB4ID0gfngsCiMgICAgIHkgPSB+eSwKIyAgICAgZnJhbWUgPSB+ZiwKIyAgICAgdHlwZSA9ICdzY2F0dGVyJywKIyAgICAgbW9kZSA9ICdtYXJrZXJzJywKIyAgICAgc2hvd2xlZ2VuZCA9IEYKIyAgICkKZmlnIDwtIGNvbXBhcmVkX2luZmVjdGlvbnNfYW5kX2RlYXRoc19kYXRlcyAlPiUgcGxvdF9seSh4PX5lc3RpbWF0ZWRfaW5mZWN0aW9uc19sb2NrZG93biwgeT1+ZXN0aW1hdGVkX2RlYXRoc19sb2NrZG93biwgZnJhbWUgPSB+ZGF0ZSwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZT0nbWFya2VycycpCgoKIyBmaWcgPC0gZmlnICU+JSBsYXlvdXQoCiMgICAgIHhheGlzID0gbGlzdCgKIyAgICAgICB0eXBlID0gImxvZyIKIyAgICAgKQojICAgKQogCgpmaWcyIDwtIGZpZyAlPiUgYW5pbWF0aW9uX3NsaWRlcihjdXJyZW50dmFsdWU9bGlzdChwcmVmaXggPSAiRGF0ZSIsIGZvbnQgPSBsaXN0KGNvbG9yPSdyZWQnKSkpCmZpZzIKCmBgYAoK